using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml.XPath;
using Lucene.Net.Analysis;
using SearchTools.Exceptions;
using SearchTools.Providers;
using StructureMap;
using umbraco;

namespace Searchtools.Providers
{
    /// <summary>
    /// Fetches a frequency
    /// </summary>
    [Pluggable("PageUnstructured", "")]
    public class PageUnstructured : IMetadataProvider
    {
        #region IMetadataProvider Members

        /// <summary>
        /// Return value for field
        /// </summary>
        /// <param name="key">Field specifier</param>
        /// <returns>Term list</returns>
        public Dictionary<string, int> this[string key]
        {
            get
            {
                XPathNavigator pageXml = library.GetXmlNodeCurrent().Current;
                return ProcessUmbracoNode(key, pageXml);
            }
        }

        /// <summary>
        /// Return value for field for item specified by key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <returns>Term list</returns>
        public Dictionary<string, int> this[string key, string field]
        {
            get
            {
                XPathNavigator pageXml = library.GetXmlNodeById(key).Current;

                return ProcessUmbracoNode(key, pageXml);
            }
        }

        #endregion

        private static Dictionary<string, int> ProcessUmbracoNode(string field, XPathNavigator pageXml)
        {
            //First attempt to find attribute
            XPathNodeIterator data = pageXml.Select("./@" + field);

            if (data.MoveNext())
            {
                return GetTermsFromNode(data);
            }

            //Fall through to data element
            data = pageXml.Select("./data[@alias='" + field + "']");

            if (data.MoveNext())
            {
                return GetTermsFromNode(data);
            }

            throw new SearchToolsException(string.Format("Could not locate attibute or data with key '{0}'", field));
        }

        private static Dictionary<string, int> GetTermsFromNode(XPathNodeIterator data)
        {
            Dictionary<string, int> scratch = new Dictionary<string, int>();
            StopAnalyzer anal = new StopAnalyzer(new FileInfo("DefaultStopWords.txt"));

            TokenStream tStr = anal.TokenStream("", new StringReader(
                                                        Regex.Replace(data.Current.Value, "<[^>]*>", "")));

            Token tok = tStr.Next();
            while (tok != null)
            {
                if (!scratch.ContainsKey(tok.TermText()))
                {
                    scratch.Add(tok.TermText(), 1);
                }
                else
                {
                    ++scratch[tok.TermText()];
                }

                tok = tStr.Next();
            }

            return scratch;
        }
    }

    [Pluggable("PageStructuredAsCSV", "")]
    internal class PageStructuredAsCSV : IMetadataProvider
    {
        #region IMetadataProvider Members

        /// <summary>
        /// Return value for field for current item 
        /// </summary>
        /// <param name="field">Field specifier</param>
        /// <returns>Term list</returns>
        public Dictionary<string, int> this[string field]
        {
            get { throw new NotImplementedException(); }
        }

        /// <summary>
        /// Return value for field for item specified by key
        /// </summary>
        /// <param name="key"></param>
        /// <param name="field"></param>
        /// <returns>Term list</returns>
        public Dictionary<string, int> this[string key, string field]
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }
}